 #include"tcpServer.h"
#include"logger.h"
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<string.h>//cstring
#include"public.h"
#include"IpAddressPort.h"
 
 //socket bind listen
    TcpServer::TcpServer(const IpAddressPort&ipAddressAndPort)
    {
        m_lfd = socket(AF_INET,SOCK_STREAM,0);
        if(-1==m_lfd)
        {
            LOG_FATAL<<strerror(errno);
        }
        struct sockaddr_in ser;
        ser.sin_family=AF_INET;
        ser.sin_addr.s_addr=inet_addr(ipAddressAndPort.GetIpAddress().c_str());
        ser.sin_port=htons(ipAddressAndPort.GetPort());
        int res=bind(m_lfd,(struct sockaddr*)&ser,sizeof(ser));
        if(-1==res)
        {
            LOG_FATAL<<strerror(errno);
        }
        if(-1==listen(m_lfd,5))
        {
            LOG_FATAL<<strerror(errno);
        }
    }

    //close
    TcpServer::~TcpServer()
    {
        if(-1==close(m_lfd))
        {
            LOG_FATAL<<strerror(errno);
        }
    }

    //从一个全连接队列中获取一个完成三次握手的cfd
    int TcpServer::Accept()
    {
        struct sockaddr_in cli;
        socklen_t len=sizeof(cli);
        int cfd=accept(m_lfd,(struct sockaddr*)&cli,&len);
        if(-1==cfd)
        {
            LOG_ERROR<<strerror(errno);
            return -1;
        }
        else
        {
            char clientIpBuf[SMALL_BUF_LEN]={0};
            if(!inet_ntop(AF_INET,&cli.sin_addr,clientIpBuf,SMALL_BUF_LEN))
            {
                LOG_ERROR<<strerror(errno);
            } 
            else
            {
                //打印客户端ip+port:数据转换  网络字节序---》本机字节序
                std::string clientIp(clientIpBuf);
                unsigned short clientPort=ntohs(cli.sin_port);
                IpAddressPort ipAddressPort(std::move(clientIp),std::move(clientPort));
                LOG_INFO<<ipAddressPort.ToString();
            }
        }
        return cfd;
    }

    int TcpServer::SendMsg(int cfd,const std::string &msg)
    {
        int res=send(cfd,msg.c_str(),strlen(msg.c_str()),0);
        if(-1==res)
        {
            LOG_ERROR<<strerror(errno);
        }
        return res;
    }

    Msg TcpServer::RecvMsg(int cfd)
    {
        char buf[MEDIAN_BUF_LEN]={0};
        int res=recv(cfd,buf,MEDIAN_BUF_LEN,0);
        if(-1==res)
        {
            LOG_ERROR<<strerror(errno);
        }
        return Msg{buf,res};
    }
    int TcpServer::GetLfd()const
    {
        return m_lfd;
    }

    // int main()
    // {
    //     IpAddressPort ser("127.0.0.1",7000);
    //     TcpServer server(ser);
    //     while(1)
    //     {
    //         int cfd=server.Accept();
    //         if(cfd<0)
    //         {
    //             continue;
    //         }
    //         std::cout<<"accept:"<<cfd<<std::endl;
    //         while(1)
    //         {
    //             Msg m=server.RecvMsg(cfd);
    //             LOG_INFO<<m.ToString();
    //             if(m.m_numberofRecvBytes<=0)
    //             {
    //                 break;
    //             }
    //             server.SendMsg(cfd,"ok!");
    //         }
    //         close(cfd);
    //     }
    //     server.~TcpServer();
       
    //     return 0;
    // }